﻿using Model;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace 固高控制
{
    public partial class CoordinateAxisControl : UserControl
    {
        //创建画布
        Graphics g;
        //创建一个集合用来存储节点
        public List<NodeClass> nodes = new List<NodeClass>();

        //绘制的图形
        public List<Shape> shapes = new List<Shape>();
        //是否绘制圆形
        bool IsDrawingCircle;
        //是否绘制矩形
        bool IsDrawingRectangle;

        // 用以绘制轨迹
        private List<Trajectory> trajectories = new List<Trajectory>();
        private Timer animationTimer;
        private int animationStep = 0;

        //机械臂的坐标点：X轴
        private int _movePointX = 0;
        [Category("机械坐标属性")]//属性窗口类别
        [Description("机械臂X坐标")]//机械臂X坐标
        public int MovePointX
        {
            get
            {
                //由于是四象限的坐标系，所以需要将X轴坐标转换
                if (_movePointX != 0)
                {
                    return _movePointX - this.Width / 2;
                }
                else
                {
                    return 0;
                }
            }
            set
            {
                //由于是四象限的坐标系，所以需要将X轴坐标转换
                if (_movePointX != value)
                {
                    _movePointX = value + this.Width / 2;
                }
                //刷新控件绘制内容，触发OnPaint方法
                this.Invalidate();
            }
        }

        //机械臂的坐标点：Y轴
        private int _movePointY = 0;

        [Category("机械坐标属性")]//属性窗口类别
        [Description("机械臂Y坐标")]//机械臂Y坐标
        public int MovePointY
        {
            get
            {
                //由于是四象限的坐标系，所以需要将Y轴坐标转换
                if (_movePointY != 0)
                {
                    return this.Height / 2 - _movePointY;
                }
                else
                {
                    return 0;
                }
            }
            set
            {
                //由于是四象限的坐标系，所以需要将Y轴坐标转换
                if (_movePointY != value)
                {
                    _movePointY = this.Height / 2 - value;
                }
                //刷新控件绘制内容，触发OnPaint方法
                this.Invalidate();
            }
        }

        private bool _isShowCross = true;
        [Category("机械坐标属性")]//属性窗口类别
        [Description("是否显示十字架")]//是否显示十字架
        public bool IsShowCross
        {
            get { return _isShowCross; }
            set
            {
                _isShowCross = value;
                //刷新控件绘制内容，触发OnPaint方法
                this.Invalidate();
            }
        }

        private Color _crossColor = Color.DarkGray;

        [Category("机械坐标属性")]//属性窗口类别
        [Description("十字架颜色")]//十字架颜色
        public Color CrossColor
        {
            get
            {
                return _crossColor;
            }
            set
            {
                _crossColor = value;
                //刷新控件绘制内容，触发OnPaint方法
                this.Invalidate();
            }
        }

        // 添加一个新的属性来控制是否可以绘制
        private bool _canDraw = false;
        [Category("机械坐标属性")]
        [Description("是否允许绘制")]
        public bool CanDraw
        {
            get { return _canDraw; }
            set { _canDraw = value; }
        }

        private bool isDrawing = false;
        private Shape currentShape = null;
        // 添加一个专门用于轨迹点绘制模式的标志
        private bool isPathDrawingMode = false;
        private List<Point> pathPoints = new List<Point>();
        // 添加一个变量来跟踪当前选中的节点
        private NodeClass selectedNode = null;
        //设置界面上选择的节点
        public Action<string> actionSetSelectedNode = null;
        //创建形状路径的索引
        private int shapeIndex = 1;
        //创建委托用来更新界面的ListBox控件显示的形状
        public Action<List<Shape>> actionRefreshShapeToListBox = null;
        // 添加循环标志
        private bool isLoopAnimation = false;
        //P2P: Move
        public Action<int, int> acP2PMove = null;
        //移动的轨迹
        private Queue<Point> points = new Queue<Point>();
        //起始点
        Point startPoint;
        //当前绘制的点
        Point currerPoint;


        public CoordinateAxisControl()
        {
            InitializeComponent();
            //减少闪缩
            this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            //双缓冲
            this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
            //当控件的大小发生变化时，重绘控件
            this.SetStyle(ControlStyles.ResizeRedraw, true);
            //控件将接收鼠标消息
            this.SetStyle(ControlStyles.Selectable, true);
            //控件支持透明色
            this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
            //设置界面由用户重绘而成
            this.SetStyle(ControlStyles.UserPaint, true);

            // 初始化定时器
            animationTimer = new Timer();
            animationTimer.Interval = 100; // 每100毫秒更新一次
            animationTimer.Tick += AnimationTimer_Tick;

            // 添加鼠标事件处理
            this.MouseDown += CoordinateAxisControl_MouseDown;
            this.MouseMove += CoordinateAxisControl_MouseMove;
            this.MouseUp += CoordinateAxisControl_MouseUp;

        }

        private int currentShapeIndex = 0; // 当前正在绘制的形状索引

        // 添加定时器事件处理
        private void AnimationTimer_Tick(object sender, EventArgs e)
        {
            if (currentShapeIndex >= shapes.Count)
            {
                animationTimer.Stop();
                return;
            }

            if (currentShapeIndex >= shapes.Count)
            {
                if (isLoopAnimation)
                {
                    // 如果是循环模式，重置索引从头开始
                    currentShapeIndex = 0;
                    animationStep = 0;
                }
                else
                {
                    // 非循环模式，停止动画
                    animationTimer.Stop();
                    return;
                }
            }

            var currentShape = shapes[currentShapeIndex];
            //animationStep++;

            // 如果当前形状的轨迹绘制完成，移到下一个形状
            if (animationStep >= currentShape.TrajectoryPoints.Count)
            {
                currentShapeIndex++;
                animationStep = 0;

                // 如果所有形状都绘制完成且不是循环模式，停止动画
                if (currentShapeIndex >= shapes.Count && !isLoopAnimation)
                {
                    animationTimer.Stop();
                    return;
                }
            }

            this.Invalidate();
        }

        // 添加动画控制方法
        public void StartAnimation()
        {
            currentShapeIndex = 0;
            animationStep = 0;
            animationTimer.Start();
        }

        public void StopAnimation()
        {
            animationTimer.Stop();
        }


        // 开始循环动画
        public void StartLoopAnimation()
        {
            isLoopAnimation = true;
            currentShapeIndex = 0;
            animationStep = 0;
            animationTimer.Start();
        }

        // 停止循环动画
        public void StopLoopAnimation()
        {
            isLoopAnimation = false;
            animationTimer.Stop();
        }



        /// <summary>
        /// 此方法是绘制控件的方法
        /// 每次界面刷新都会调用此方法
        /// </summary>
        /// <param name="e"></param>
        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);

            //获取整个控件的界面作为画布
            g = e.Graphics;
            //设置线段抗锯齿
            g.SmoothingMode = SmoothingMode.HighQuality;
            //设置字体抗锯齿
            g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
            //设置线段平滑
            g.PixelOffsetMode = PixelOffsetMode.HighQuality;

            //绘制X轴与Y轴
            DrawBackground(g);

            // 绘制轨迹点
            if (isPathDrawingMode)
            {
                foreach (var point in pathPoints)
                {
                    // 绘制点
                    using (SolidBrush brush = new SolidBrush(Color.Blue))
                    {
                        e.Graphics.FillEllipse(brush, point.X - 3, point.Y - 3, 6, 6);
                    }

                    // 显示坐标
                    string coordinates = $"({point.X - Width / 2}, {Height / 2 - point.Y})";
                    using (Font font = new Font("Arial", 8))
                    using (SolidBrush brush = new SolidBrush(Color.Black))
                    {
                        e.Graphics.DrawString(coordinates, font, brush, point.X + 5, point.Y - 15);
                    }
                }

                // 绘制连接线
                if (pathPoints.Count > 1)
                {
                    using (Pen pen = new Pen(Color.Blue, 1))
                    {
                        for (int i = 0; i < pathPoints.Count - 1; i++)
                        {
                            e.Graphics.DrawLine(pen, pathPoints[i], pathPoints[i + 1]);
                        }
                    }
                }
            }

            // 1. 绘制当前正在绘制的形状
            if (isDrawing && currentShape != null)
            {
                currentShape.Draw(g);
            }

            if (animationTimer.Enabled)
            {

                //动画模式:  绘制所有已完成的形状
                for (int i = 0; i < currentShapeIndex; i++)
                {
                    var shape = shapes[i];
                    shape.Draw(e.Graphics);
                    // 绘制完整轨迹
                    for (int j = 0; j < shape.TrajectoryPoints.Count - 1; j++)
                    {
                        using (Pen pen = new Pen(shape.Color, 3))
                        {
                            e.Graphics.DrawLine(pen, shape.TrajectoryPoints[j], shape.TrajectoryPoints[j + 1]);
                        }
                    }
                }

                // 绘制当前正在动画的形状
                if (currentShapeIndex < shapes.Count)
                {
                    var shape = shapes[currentShapeIndex];
                    shape.Draw(e.Graphics);

                    // 绘制当前进度的轨迹
                    for (int i = 0; i < Math.Min(animationStep, shape.TrajectoryPoints.Count - 1); i++)
                    {
                        using (Pen pen = new Pen(shape.Color, 3))
                        {
                            e.Graphics.DrawLine(pen,
                                shape.TrajectoryPoints[i],
                                shape.TrajectoryPoints[i + 1]);
                        }
                    }

                    //绘制当前轨迹点的十字架
                    if (animationStep < shape.TrajectoryPoints.Count)
                    {
                        if (points.Count == 0) points.Enqueue(shape.TrajectoryPoints[animationStep]);
                        if (points.Count > 0)
                        {
                            //设置起始点，由于0,0需要进行坐标转换
                            startPoint.X = MovePointX + this.Width / 2;
                            startPoint.Y = this.Height / 2 - MovePointY;
                            //打印显示坐标点
                            //Console.WriteLine("当前点：({0},{1})，目标点：({2}，{3})", startPoint.X, startPoint.Y, currerPoint.X, currerPoint.Y);
                            if (animationStep == 0 || (startPoint.X == currerPoint.X && startPoint.Y == currerPoint.Y))
                            {
                                animationStep++;
                                // 取坐标点
                                currerPoint = points.Dequeue();
                                //就行转换
                                int posX = (currerPoint.X - this.Width / 2) * 250;
                                int posY = (this.Height / 2 - currerPoint.Y) * 250;
                                //Console.WriteLine("前往：{0}，{1}", posX, posY);
                                //会自动更新坐标点
                                acP2PMove(1, -posX);
                                acP2PMove(2, posY);
                            }
                        }
                    }
                }

            }
            else
            {
                //非动画模式：绘制所有已完成的形状
                foreach (var shape in shapes)
                {
                    shape.Draw(e.Graphics);
                    // 绘制完整轨迹
                    if (shape.TrajectoryPoints.Count > 1)
                    {
                        using (Pen pen = new Pen(shape.Color, 3))
                        {
                            for (int i = 0; i < shape.TrajectoryPoints.Count - 1; i++)
                            {
                                e.Graphics.DrawLine(pen,
                                    shape.TrajectoryPoints[i],
                                    shape.TrajectoryPoints[i + 1]);
                            }
                        }
                    }
                }
            }


            //绘制节点
            foreach (NodeClass item in nodes)
            {
                //由于是四象限的坐标系,item.X与item.Y是相对于左上角的坐标,因此我们需要进行转换
                int x = item.X + this.Width / 2;
                int y = this.Height / 2 - item.Y;

                //绘制节点-圆形
                Color nodeColor = (item == selectedNode) ? Color.SeaGreen : item.NodeColor;
                g.FillEllipse(new SolidBrush(nodeColor), x - 6, y - 6, 12, 12);



                //绘制节点-名称（在圆点正上方绘制）
                g.DrawString(item.Name, new Font("微软雅黑", 8), new SolidBrush(Color.Black), new Point(x - 10, y - 25));


                //绘制节点-坐标
                g.DrawString(string.Format("({0},{1})", item.X, item.Y), new Font("微软雅黑", 8), new SolidBrush(Color.Black), new Point(x + 5, y + 5));

            }

            //判断是否需要显示十字架
            if (IsShowCross)
            {
                //绘制十字架用来表示机械点
                DrawCross(g, new Pen(CrossColor, 1), _movePointX, _movePointY, 15, 15, 15);
            }


        }

        /// <summary>
        /// 重写鼠标点击事件
        /// </summary>
        /// <param name="e"></param>
        protected override void OnMouseDown(MouseEventArgs e)
        {
            base.OnMouseDown(e);

            // 检查是否点击了某个节点
            NodeClass clickedNode = null;
            foreach (NodeClass node in nodes)
            {
                int x = node.X + this.Width / 2;
                int y = this.Height / 2 - node.Y;

                // 检查点击位置是否在节点范围内
                Rectangle nodeBounds = new Rectangle(x - 6, y - 6, 12, 12);
                if (nodeBounds.Contains(e.Location))
                {
                    clickedNode = node;
                    break;
                }
            }

            // 更新选中的节点
            if (selectedNode != clickedNode)
            {
                selectedNode = clickedNode;
                // 通知外部选中的节点
                actionSetSelectedNode?.Invoke(selectedNode?.Name);
                this.Invalidate(); // 重绘控件
            }
        }

        /// <summary>
        /// 通过节点名称设置选中状态
        /// </summary>
        /// <param name="nodeName">节点名称，如 "1号"</param>
        public void SelectNodeByName(string nodeName)
        {
            // 查找指定名称的节点
            NodeClass targetNode = null;
            foreach (NodeClass node in nodes)
            {
                if (node.Name == nodeName)
                {
                    targetNode = node;
                    break;
                }
            }

            // 更新选中的节点
            if (selectedNode != targetNode)


            {
                selectedNode = targetNode;
                this.Invalidate(); // 重绘控件
            }
        }

        // 鼠标按下事件处理
        private void CoordinateAxisControl_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left && CanDraw)
            {
                if (isPathDrawingMode)
                {

                    // 在轨迹点绘制模式下，添加点
                    pathPoints.Add(e.Location);
                    // 只在绘制过程中更新显示，不立即创建形状
                    this.Invalidate();

                }
                else
                {
                    isDrawing = true;
                    if (IsDrawingCircle)
                    {
                        currentShape = new Circle("圆形-" + (shapeIndex++), e.Location, Color.DarkSlateGray);
                    }
                    else if (IsDrawingRectangle)
                    {
                        currentShape = new RectangleShape("矩形-" + (shapeIndex++), e.Location, Color.DarkOliveGreen);
                    }
                    else // 自定义路径模式
                    {
                        currentShape = new CustomPathShape("自定义轨迹-" + (shapeIndex++), e.Location, Color.Green);
                    }
                    //强制刷新界面
                    this.Invalidate();
                }
            }
        }

        // 鼠标移动事件处理
        private void CoordinateAxisControl_MouseMove(object sender, MouseEventArgs e)
        {
            if (isDrawing && currentShape != null && CanDraw)
            {
                currentShape.Update(e.Location);
                this.Invalidate();
            }
        }

        // 鼠标释放事件处理
        private void CoordinateAxisControl_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left && isDrawing && CanDraw)
            {
                isDrawing = false;
                if (currentShape != null)
                {
                    // 确保最后一个点被添加
                    currentShape.Update(e.Location);
                    AddShape(currentShape); // 使用 AddShape 方法
                    currentShape = null;
                }
                this.Invalidate();
            }
        }

        // 添加清除所有图形的方法
        public void ClearAll()
        {
            shapes.Clear();
            trajectories.Clear();
            pathPoints.Clear();
            currentShape = null;
            isDrawing = false;
            actionRefreshShapeToListBox?.Invoke(shapes); // 更新 ListBox
            this.Invalidate();
        }

        public void AddShape(Shape shape)
        {
            shapes.Add(shape);
            actionRefreshShapeToListBox?.Invoke(shapes); // 更新 ListBox
        }

        public void SetPathDrawingMode(bool enabled)
        {
            isPathDrawingMode = enabled;
            if (enabled)
            {
                // 进入轨迹点绘制模式
                CanDraw = true;
                // 清空当前的轨迹点
                pathPoints.Clear();
            }
            else
            {
                // 退出轨迹点绘制模式时，如果有足够的点，创建一个新的形状
                if (pathPoints.Count > 1)
                {
                    CustomPathShape pathShape = new CustomPathShape("轨迹点坐标-" + (shapeIndex++), pathPoints[0], Color.Blue);
                    //用直线的方式绘制轨迹
                    for (int i = 0; i < pathPoints.Count; i++)
                    {
                        pathShape.Update(pathPoints[i]);
                    }
                    //shapes.Add(pathShape);
                    AddShape(pathShape);
                }
                // 清空轨迹点
                pathPoints.Clear();
            }
            Invalidate();
        }

        // 添加模式切换方法
        public void SetDrawingMode(string mode)
        {
            // 如果正在轨迹点绘制模式，不允许切换其他模式
            if (isPathDrawingMode)
                return;

            // 重置所有绘制状态
            IsDrawingCircle = false;
            IsDrawingRectangle = false;
            CanDraw = true;

            // 根据模式设置对应的绘制类型
            switch (mode)
            {
                case "Circle":
                    IsDrawingCircle = true;
                    break;
                case "Rectangle":
                    IsDrawingRectangle = true;
                    break;
                case "CustomPath":
                    // 自定义路径模式保持默认状态
                    break;
                case "None":
                    CanDraw = false;  // 禁用绘制
                    break;
            }
        }

        //创建方法绘制背景
        public void DrawBackground(Graphics panelGraphics)
        {
            //绘制四象限坐标系-X轴
            //设置画笔为带箭头: 
            Pen pen = new Pen(Color.DarkGray, 3);
            //三角形箭头：箭头大小为3，4，箭头是否闭合
            pen.CustomEndCap = new AdjustableArrowCap(3, 4, true);
            panelGraphics.DrawLine(pen, 0, this.Height / 2, this.Width, this.Height / 2);
            panelGraphics.DrawLine(pen, this.Width / 2, this.Height, this.Width / 2, 0);

            //设置绘制网格
            pen.Width = 2;
            //绘制X轴刻度
            for (int i = 0; i < this.Width; i += 40)
            {
                panelGraphics.DrawLine(pen, i, this.Height / 2 - 5, i, this.Height / 2 + 5);
            }
            //绘制Y轴刻度，从下往上绘制
            for (int i = this.Height; i > 0; i -= 40)
            {
                panelGraphics.DrawLine(pen, this.Width / 2 - 5, i, this.Width / 2 + 5, i);
            }

            //绘制X轴刻度值
            Font font = new Font("微软雅黑", 8);
            Brush brush = new SolidBrush(Color.DarkGray);
            for (int i = 0; i < this.Width; i += 40)
            {
                panelGraphics.DrawString((i - this.Width / 2).ToString(), font, brush, i, this.Height / 2 + 5);
            }
            //绘制Y轴刻度值
            for (int i = this.Height; i > 0; i -= 40)
            {
                panelGraphics.DrawString((this.Height / 2 - i).ToString(), font, brush, this.Width / 2 + 5, i);
            }

            //绘制原点
            //panelGraphics.FillEllipse(new SolidBrush(Color.DarkGray), this.Width / 2 - 4, this.Height / 2 - 4, 8, 8);

            pen = new Pen(Color.DarkGray, 1);
            pen.DashStyle = DashStyle.Dash;
            //绘制X轴，虚线构成
            for (int i = 0; i < this.Width; i += 40)
            {
                panelGraphics.DrawLine(pen, i, 0, i, this.Height);
            }
            //绘制Y轴，虚线构成
            for (int i = this.Height; i > 0; i -= 40)
            {
                panelGraphics.DrawLine(pen, 0, i, this.Width, i);
            }
        }

        /// <summary>
        /// 绘制十字架，用于标记机械臂的坐标点
        /// </summary>
        /// <param name="g">画布</param>
        /// <param name="pen">画笔</param>
        /// <param name="x">中心点X坐标</param>
        /// <param name="y">中心点Y坐标</param>
        /// <param name="width">矩形的宽</param>
        /// <param name="height">矩形的高</param>
        /// <param name="length">十字的长度</param>
        public void DrawCross(Graphics g, Pen pen, int x, int y, int width, int height, int length)
        {
            //绘制中心点
            Point CentePoint = new Point(x, y);
            //矩形的左上角坐标
            Point Top = new Point(CentePoint.X - width / 2, CentePoint.Y - height / 2);
            //绘制十字架线段-1
            g.DrawLine(pen, CentePoint, new Point(CentePoint.X + length, CentePoint.Y));
            //绘制十字架线段-2
            g.DrawLine(pen, CentePoint, new Point(CentePoint.X - length, CentePoint.Y));
            //绘制十字架线段-3
            g.DrawLine(pen, CentePoint, new Point(CentePoint.X, CentePoint.Y + length));
            //绘制十字架线段-4
            g.DrawLine(pen, CentePoint, new Point(CentePoint.X, CentePoint.Y - length));
            //绘制矩形
            g.DrawRectangle(pen, new Rectangle(Top.X, Top.Y, width, height));
            //右下角显示坐标值
            g.DrawString(string.Format("({0},{1})", MovePointX, MovePointY), new Font("微软雅黑", 8), new SolidBrush(Color.Black), new Point(x + 5, y + 5));
        }

    }
}

